Pesquise o número de 'txt A' e substitua no arquivo csv

Pesquise o número de 'txt A' e substitua no arquivo csv

Tenho tentado isso de várias maneiras, mas ainda não consigo alcançar o que quero. Desculpe, ainda estou aprendendo.

O que eu quero é assim:

Arquivo A.txt

5844
6069
6303
6309

Arquivo B.txt

// some comment
// some  explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,

Quero alterar o número pesquisado de A.txt e comentar a linha em B.txt. às vezes o número pesquisado pode aparecer em outra coluna, então só mudará a primeira coluna.

Resultado:

// some comment
// some  explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,

Eu tentei e às vezes dava errado e mudava a outra coluna também. Então usei algo assim, é muito longo e não é fácil de modificar,

awk -F ',' '/^5844/ && $1="5844"{$1="//5844"}1' b.txt > c.txt; cp c.txt ba.txt; rm -rf b.txt; mv ba.txt b.txt

e às vezes também é necessário remover o separador ','.

Por favor ajude, muito obrigado.

Responder1

$ awk -F , 'FNR==NR { data[$1]=1; next } $1 in data { $0 = "//" $0 }; 1' 'File A.txt' 'File B.txt'
500,5,4,8,,,
5535,5,4,6069,,,
2121,5,4,8,,,
//5844,5,4,5844,,,
//6069,5,4,8,,,

O que estou fazendo aqui é primeiro ler os números File A.txtcomo chaves no array associativo data. Em seguida, testo cada primeiro campo File B.txtpara ver se é uma chave dataou não. Se for, eu acrescento //a linha atual. Todas as linhas, modificadas ou não, são impressas.

O FNR==NRteste só será verdadeiro durante a leitura do primeiro arquivo na linha de comando e o bloco termina com next. Isso significa que o primeiro bloco é executado apenas para o primeiro arquivo, enquanto o segundo bloco é executado para o segundo arquivo, se o primeiro campo for uma chave no dataarray.

O 1no final aciona a saída e pode ser substituído por { print }.

O acima só iráadicionar //às linhas nos segundos arquivos que correspondem aos números do primeiro arquivo. Para tambémremover //de linhasnãocorrespondido (ou seja, para lidar com sua pergunta atualizada):

$ cat 'File B.txt'
// some comment
// some  explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,
$ awk -F , 'FNR==NR { data[$1]=1; next } FNR > 2 { if ($1 in data) $0 = "//" $0; else sub("^//","") }; 1' 'File A.txt' 'File B.txt'
// some comment
// some  explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,

O awkcomando assume que você deseja passar as duas primeiras linhas File B.txtinalteradas (é disso que o FNR > 2teste cuida). O FNR > 2bloco testa se o número é digitado dataou não e, se for, a linha é comentada, mas se não for, qualquer um //no início da linha é removido usando sub().

Em vez disso, FNR > 2você poderia usar /^\/\/ /para testar um comentário na parte superior do arquivo. Isso exigiria que todos esses comentários sempre começassem com //seguido de um espaço.

As variáveis ​​especiais NRe FNRarmazenam o número de linhas lidas até o momento no total ( NR) e no arquivo atual ( FNR).


As vírgulas "desapareceriam" se eu alterasse apenas o primeiro campo, $1 = "//" $1pois isso reformaria o registro usando o valor atual de OFS(um espaço por padrão). Você pode evitar isso usando BEGIN { OFS=FS }, que seria definido OFScomo o caractere vírgula (ou qualquer caractere usado -Fna linha de comando).

informação relacionada