Найти число из «txt A» и заменить в файл csv

Найти число из «txt A» и заменить в файл csv

Я пробовал много способов, но все еще не могу достичь того, чего хочу. Извините, я все еще учусь.

Я хочу вот этого:

Файл A.txt

5844
6069
6303
6309

Файл 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,,,

Я хочу изменить искомый номер из A.txt и закомментировать строку в 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 ',' '/^5844/ && $1="5844"{$1="//5844"}1' b.txt > c.txt; cp c.txt ba.txt; rm -rf b.txt; mv ba.txt b.txt

и иногда также удаляют разделитель «,».

Пожалуйста, помогите, большое спасибо.

решение1

$ 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,,,

Что я делаю здесь, так это сначала считываю числа из File A.txtкак ключи в ассоциативном массиве data. Затем я проверяю каждое первое поле из, File B.txtчтобы увидеть, является ли оно ключом dataили нет. Если это так, я добавляю //к текущей строке. Затем печатаются все строки, измененные или нет.

Тест FNR==NRбудет истинным только при чтении из первого файла в командной строке, и блок заканчивается на next. Это означает, что первый блок выполняется только для первого файла, в то время как второй блок выполняется для второго файла, если первое поле является ключом в массиве data.

В 1конце активируется вывод и может быть заменено на { print }.

Вышеуказанное будет толькодобавлять //к строкам во вторых файлах, соответствующим номерам в первом файле. Такжеудалять //из линийнетсопоставил (т.е. обработал ваш обновленный вопрос):

$ 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,,,

Команда awkпредполагает, что вы хотите передать первые две строки File B.txtбез изменений (это то, о чем FNR > 2заботится тест). FNR > 2Блок проверяет, является ли число ключом dataили нет, и если это так, строка закомментирована, но если нет, все //в начале строки удаляется с помощью sub().

Вместо FNR > 2вы могли бы использовать /^\/\/ /для проверки комментария в верхней части файла. Это потребовало бы, чтобы все такие комментарии всегда начинались с , //за которым следует пробел.

Специальные переменные NRи FNRсодержат общее количество прочитанных строк ( NR) и в текущем файле ( FNR).


Запятые «исчезнут», если я изменю только первое поле с помощью , $1 = "//" $1что переформирует запись, используя текущее значение OFS(пробел по умолчанию). Вы можете предотвратить это, используя BEGIN { OFS=FS }, который установит OFSсимвол запятой (или любой другой символ, который вы используете -Fв командной строке).

Связанный контент