sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
Я ожидаю, что этот sed script будет вставлять вкладку в шрифт каждой строки в $filename
, но это не так. По какой-то причине он вместо этого вставляет t. Странно..
sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
Я ожидаю, что этот sed script будет вставлять вкладку в шрифт каждой строки в $filename
, но это не так. По какой-то причине он вместо этого вставляет t. Странно..
Не все версии sed
понимают \t
. Просто вставьте вместо него буквальную вкладку (нажмите Ctrl - V, затем Tab).
Используя Bash, вы можете вставить символ TAB программно так:
TAB=$'\t'
echo 'line' | sed "s/.*/${TAB}&/g"
echo 'line' | sed 's/.*/'"${TAB}"'&/g' # use of Bash string concatenation
Я использовал что-то вроде этого с оболочкой Bash на Ubuntu 12.04 (LTS):
Чтобы добавить новую строку с вкладкой, второй, когда первый соответствует:
sed -i '/first/a \\t second' filename
Чтобы заменить сначала вкладкой, второй:
sed -i 's/first/\\t second/g' filename
Используйте $(echo '\t')
. Вам понадобятся кавычки вокруг шаблона.
Eg. Чтобы удалить вкладку:
sed "s/$(echo '\t')//"
@sedit был на правильном пути, но немного сложно определить переменную.
Способ сделать это в bash - это использовать знак доллара перед вашей одинарной кавычкой.
$ echo -e '1\n2\n3'
1
2
3
$ echo -e '1\n2\n3' | sed 's/.*/\t&/g'
t1
t2
t3
$ echo -e '1\n2\n3' | sed $'s/.*/\t&/g'
1
2
3
Если ваша строка должна включать расширение переменной, вы можете просто процитировать строки так:
$ timestamp=$(date +%s)
$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'
1491237958 1
1491237958 2
1491237958 3
В bash $'string'
происходит "расширение ANSI-C". И это то, что большинство из нас ожидает, когда мы используем такие вещи, как \t
, \r
, \n
и т.д. От: https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting
Слова формы $'string' обрабатываются специально. Слово расширяется для строки, с замененными символами с обратной косой чертой, как указано в стандарт ANSI C. Последующие последовательности обратной косой черты, если они есть, декодируется...
Расширенный результат одинарный, как если бы знак доллара не был присутствовали.
Я лично считаю, что большинство усилий по предотвращению bash глупы, потому что избегать багизмов НЕ делает ваш код переносимым. (Ваш код будет менее хрупким, если вы отмените его до bash -eu
, чем если бы вы попытались избежать bash и использовать sh
[если вы не являетесь абсолютным ниндзя POSIX].) Но вместо того, чтобы иметь религиозный аргумент об этом, Я просто дам вам ЛУЧШИЙ * ответ.
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* Лучший ответ? Да, потому что один пример того, что большинство антивирусных скриптов bash ошибается в своем коде, использует echo '\t'
, как в @robrecord answer. Это будет работать для эха GNU, но не эхо BSD. Это объясняется The Open Group в http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16
Вам не нужно использовать sed
для подстановки, если на самом деле вы просто хотите вставить вкладку перед строкой. Замена для этого случая - дорогостоящая операция по сравнению с просто ее распечаткой, особенно когда вы работаете с большими файлами. Его легче читать также как не регулярное выражение.
например, используя awk
awk '{print "\t"$0}' $filename > temp && mv temp $filename
sed
не поддерживает \t
, а также другие escape-последовательности, такие как \n
. Единственный способ, которым я нашел это, - фактически вставить символ табуляции в script с помощью sed
.
Тем не менее, вы можете рассмотреть возможность использования Perl или Python. Здесь короткий Python script я написал, что я использую для всех потоков regex'ing:
#!/usr/bin/env python
import sys
import re
def main(args):
if len(args) < 2:
print >> sys.stderr, 'Usage: <search-pattern> <replace-expr>'
raise SystemExit
p = re.compile(args[0], re.MULTILINE | re.DOTALL)
s = sys.stdin.read()
print p.sub(args[1], s),
if __name__ == '__main__':
main(sys.argv[1:])
Я использовал это на Mac: -
sed -i '' $'$i\\\n\\\thello\n' filename
Вместо BSD sed я использую perl:
[email protected]:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
hi