Почему двойное цитирование расширения массива здесь здесь документ не работает?

awk '{ printf "%-30s%10s%10s%20s\n",$1,"IN","A","192.168.100.10"; }' file
-121--157278-

В bash:

for i in {1...152}
do
    sed -i.bak -e "s/[[i]]/[[$i]]/g plot_$i
done 

Этот сценарий запускает sed для каждого файла и резервирует их перед заменой последовательности.

-121--288924-

Просто переместите вывод в столбец -t :

sed 's/$/ IN A 192.168.155.128/' db.malware-host-only | column -t > tmp
mv tmp db.malware-host-only

Можно использовать параметр -o для расширения мест между столбцами:

column -t -o '      '

Нельзя использовать sed -i с этим, поэтому вывод во временный файл, а затем переименовать его в исходное имя.

0
18.11.2018, 04:47
2 ответа

Другой ответ в основном звучит так: «Потому что так сказано в руководстве », но я думаю, что за таким поведением есть некоторое обоснование .

This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input […] for a command.

[…]

If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion […].

(упор мой ).

Рассмотрим основные причины цитирования чего-либо в командной строке:

  1. чтобы сообщить оболочке, как разделить строку и создать список аргументов (два аргумента a bпротив одного аргумента"a b");
  2. , чтобы сообщить оболочке, следует ли выполнять расширения(''или ""или )без кавычек.

Первая причина неприменима при создании стандартного ввода, поскольку стандартный ввод представляет собой поток и в нем нет понятия количества аргументов. Вторая причина может быть применима, но выбор дизайна для управления расширениями исключительно путем цитирования или не цитирования слова("EOF"по сравнению сEOF)делает ее недействительной.

What shall I do?

Помните, что с помощью этого документа вы создаете поток. Причины использования кавычек, которые не должны появляться в нем, признаны недействительными. По сути, предпосылкой является то, что каждая используемая вами цитата должна появляться в потоке.

Если бы это сработало так, как вы ожидали, то неэкранированные кавычки исчезли бы без какой-либо разницы . Я предполагаю, что здесь документ будет поддерживать \"и \'для обозначения цитат, которые должны сохраниться. Но это будут единственные цитаты, которые вам действительно нужно использовать. Нынешняя ситуация упрощает ситуацию.

2
28.01.2020, 02:14

Давайте посмотрим, что здесь происходит на самом деле, заменив tsortнаcat:

$ arr1=( 1 2 2 3 )
$ arr2=( 2 3 3 4 )
$ cat <<END
> "${arr1[@]}" "${arr2[@]}"
> END
"1 2 2 3" "2 3 3 4"

Как видите, здесь -документ представляет собой не что иное, как текстовую строку со значениями массивов, развернутых внутри нее. Двойные кавычки происходят из двойных кавычек в самом документе (оболочка заботится только о бите ${...}и не будет касаться символов кавычек ).

Вывод при удалении двойных кавычек будет таким же, но без двойных кавычек,

1 2 2 3 2 3 3 4

Это интерпретируется tsortкак пары

1 2   <-- first two numbers from arr1
2 3   <-- last two numbers from arr1
2 3   <-- first two numbers from arr2
3 4   <-- last two numbers from arr2

К сожалению, вы выбрали именно этот пример, так как он точно такой же, как

1 2   <-- first number from arr1 and arr2
2 3   <-- second number from arr1 and arr2
2 3   <-- etc.
3 4

т. е. записи каждого массива идут вниз по двум столбцам (по одному столбцу на массив ).

Чтобы сгенерировать этот второй список (правильно ), вы не можете использовать здесь -документ. Вместо этого вы можете использовать цикл оболочки:

for (( i=0; i<${#arr1[@]}; ++i)); do
    printf '%d %d\n' "${arr1[i]}" "${arr2[i]}"
done | tsort
1
28.01.2020, 02:14

Теги

Похожие вопросы