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.txt
como chaves no array associativo data
. Em seguida, testo cada primeiro campo File B.txt
para ver se é uma chave data
ou não. Se for, eu acrescento //
a linha atual. Todas as linhas, modificadas ou não, são impressas.
O FNR==NR
teste 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 data
array.
O 1
no 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 awk
comando assume que você deseja passar as duas primeiras linhas File B.txt
inalteradas (é disso que o FNR > 2
teste cuida). O FNR > 2
bloco testa se o número é digitado data
ou 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 > 2
você 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 NR
e FNR
armazenam 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 = "//" $1
pois 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 OFS
como o caractere vírgula (ou qualquer caractere usado -F
na linha de comando).