/ proc / self - это синтаксический сахар. Это ярлык для соединения / proc / и результата системного вызова getpid () (доступного в bash как метапеременная $$). Это может сбивать с толку, хотя в случае сценариев оболочки, поскольку многие из операторов вызывают другие процессы, в комплекте с собственными PID ... PID, которые чаще всего относятся к мертвым процессам. Учтите:
root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan 1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593
'/ bin / ls' будет оценивать путь к каталогу, разрешая его как / proc / 26563, поскольку это PID процесса - вновь созданного процесса / bin / ls - который читает содержимое файла каталог. Но к тому времени, когда следующий процесс в конвейере, в случае сценария оболочки, или к тому времени, когда появится приглашение, в случае интерактивной оболочки путь больше не существует и вывод информации относится к несуществующему процессу.
Это применимо только к внешним командам (тем, которые являются фактическими исполняемыми программными файлами, а не встроены в саму оболочку). Таким образом, вы получите разные результаты, если, скажем, используете подстановку имен файлов для получения списка содержимого каталога, вместо того, чтобы передавать имя пути внешнему процессу / bin / ls:
root@vps01:~# ls /proc/self/fd
0 1 2 3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
В первой строке оболочка создала новый процесс '/ bin / ls' с помощью системного вызова exec (), передав "/ proc / self / fd" как argv [1]. '/ bin / ls', в свою очередь, открыл каталог / proc / self / fd и прочитал, а затем распечатал его содержимое при итерации по ним.
Во второй строке, однако, негласно используется glob () для расширения списка имен файлов; они передаются как массив строк для эха.(Обычно реализуется как внутренняя команда, но часто есть также двоичный файл / bin / echo ... но эта часть на самом деле не имеет значения, поскольку echo имеет дело только со строками, которые никогда не передаются никаким системным вызовам, связанным с именами путей.)
Теперь рассмотрим следующий случай:
root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0 1 2 255
Здесь оболочка, родительский процесс для / bin / ls, сделала подкаталог / proc / self своим текущим каталогом . Таким образом, относительные пути оцениваются с его точки зрения. Я предполагаю, что это связано с семантикой файла POSIX, где вы можете создать несколько жестких ссылок на файл, включая любые открытые файловые дескрипторы. Итак, на этот раз / bin / ls ведет себя аналогично echo / proc / $$ / fd / *.
Прошу прощения, но ваш пример echo
не работает. Кажется, это работает, потому что двойные кавычки ( "
) интерпретируются bash
и никогда не передаются в sed
.
Обратите внимание на разницу между следующими двумя примерами:
$ echo "john.doe@gmail.com"
john.doe@gmail.com
$ echo "\"john.doe@gmail.com\""
"john.doe@gmail.com"
Ваша команда echo
не передает "
в sed
, поэтому кажется, что она работает, потому что нет "
для удаления в входная строка.
Если вы попытаетесь правильно экранировать "
, пример echo
не будет работать, как пример файла
:
$ echo "\"john.doe@gmail.com\"" | sed 's/"([^"]*)"/\0/g'
"john.doe@gmail.com"
Вы ] sed
имеет две ошибки:
gnu
sed. Разница в том, как они используют круглые скобки. 1
. Итак, правильная команда:
echo "\"john.doe@gmail.com\"" | sed 's/"\([^"]*\)"/\1/g'
или, если ваш sed
поддерживает расширенное регулярное выражение:
echo "\"john.doe@gmail.com\"" | sed -E 's/"([^"]*)"/\1/g'
Как упоминалось @andcoz, для этого
$ sed -i '' 's/"([^"]*)"/\0/g' ~/Desktop/emails.txt
необходимо экранировать круглые скобки
и изменить обратную ссылку
с \ 0
на \ 1
].
После модификации функциональная команда sed
выглядит следующим образом:
$ sed -i '' 's/"\([^"]*\)"/\1/g' ~/Desktop/emails.txt
gv@debian:$ cat a.txt
"john.doe@gmail.com"
gv@debian:$ sed 's#"##g' a.txt #remove all quotes
john.doe@gmail.com
gv@debian:$ cat a.txt |tr -d '"' #remove all quotes
john.doe@gmail.com
gv@debian:$ sed 's#^"##g; s#"$##g' a.txt #remove first and last quote
john.doe@gmail.com
gv@debian:$ a="\"john.doe@gmail.com\"";echo -e "$a" "\n" "${a: 1:-1}" #remove first and last char
"john.doe@gmail.com"
john.doe@gmail.com