$ echo 'F o u r s c o r e a n d' | \
txr -t '(mapcar* (opip (split-str @1 " ")
(mapcar (op regsub #/ / ""))
(cat-str @1 " "))
(get-lines))'
Four score and
$ txr -e '(awk (:begin (set fs " "))
((mf (regsub #/ / ""))))' # mf: modify fields
F o u r s c o r e a n d
Four score and
$ awk -F' ' '{for(i=1;i<=NF;i++)gsub(/ /,"",$i);print}'
F o u r s c o r e a n d
Four score and
Поскольку замена является статической, а операция замены нескольких строк настолько проста в sed
, можно создать один большой sed
скрипт для выполнения этой работы.
Предположим, что у вас есть номера строк в отдельном файле, linenos.txt
, по одному номеру строки в строке, тогда мы можем создать сценарий (GNU) sed
через
$ awk '{ printf("%dc XXXXXXXXXXXXXXX\n", $0) }' linenos.txt >script.sed
или
$ awk '{ print $0, "c XXXXXXXXXXXXXXX" }' linenos.txt >script.sed
Затем нужно применить его к файлу:
$ sed -f script.sed file >file.new
Примечание. Я никогда не запускал чрезвычайно большой sed
скрипт, поэтому я не знаю, как GNU sed
справляется с этим с точки зрения производительности.
В качестве расширения ответа @Gilles, поскольку вы говорите, что у вас есть номера строк, которые необходимо изменить в файле (который, как я предполагаю, отсортирован и называется linums
)
awk '
BEGIN { getline NEXT < "linums" }
NR == NEXT { $0 = "XXXXXXXXXXXXXXX"; getline NEXT < "linums" }
1
'
Это хорошо масштабируется для изменения несколько тысяч строк без необходимости вручную вводить эти несколько тысяч номеров строк.
В качестве альтернативы, с небольшой модификацией, вы можете взять либо номера строк, либо файл для изменения на stdin
. Я бы сделал для этого скрипт (я назвал его redact.awk
)
#!/usr/bin/awk -f
BEGIN {
LINUMS = ARGV[1]
ARGV[1] = ARGV[2]
--ARGC
getline NEXT < LINUMS
}
NR == NEXT {
$0 = "XXXXXXXXXXXXXXX"
getline NEXT < LINUMS
}
1
Затем вы можете использовать любой из:
$ ./redact.awk linums file-to-be-changed
$ ./redact.awk - file-to-be-changed
$ ./redact.awk linums -
$ ./redact.awk linums
(последние два эквивалентны)
И sed, и awk хорошо подходят для этой задачи.
sed '
26115 s/.*/XXXXXXXXXXXXXXX/
32198 s/.*/XXXXXXXXXXXXXXX/
37256 s/.*/XXXXXXXXXXXXXXX/
40001 s/.*/XXXXXXXXXXXXXXX/
40023 s/.*/XXXXXXXXXXXXXXX/
'
awk '
NR==26115 || NR==32198 || NR==37256 || NR==40001 || NR==40023 {$0 = "XXXXXXXXXXXXXXX"}
1
'
(Одинокий 1
печатает все строки после возможного преобразования, выполненного предыдущим кодом.)
sed -e '1{x;s/^/XXXXXXXXXXXXXXX/;x;}
26115bp
32198bp
37256bp
40001bp
40023bp
d
:p
g
' data_file
Сначала мы заполним пространство хранения желаемым шаблоном XXXXXXXXX
, а затем вызовем его только для нужных номеров строк, перейдя к метке :p, которая извлечет пространство хранения, которое затем будет неявно перенесено в стандартный вывод. Несоответствующие -строки удаляются (, измените d
на b
, если вы хотите их сохранить ).