Прошу прощения, но ваш пример 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'
Это для
строки:
for FILE in $LISTFILE
не означает «для каждой строки в $ LISTFILE
». Это означает «для каждого элемента в переменной $ LISTFILE
. Ваш $ LISTFILE
просто содержит путь к файлу, так что это то, что будет содержать $ FILE
.
Чтобы ваша команда для
проходила через «каждую строку содержимого $ LISTFILE
», вам придется изменить свой код, чтобы он выглядел следующим образом:
#!/bin/bash
LISTFILE="/tmp/filename"
while read FILE
do echo $FILE
done < $LISTFILE
Здесь используется цикл while
и команда read
, которая считывает «ввод» построчно. Наш вход - это содержимое вашего файла, которое мы указываем в самом конце (эта часть: <$ LISTFILE
).
В этом for
вы просто делаете одну итерацию, где значение $FILE
является значением $LISTFILE
.
Если вы хотите перебирать строки в файле, вы можете использовать read:
while read -r FILE; do
curl -XDELETE "ADDRESS:PORT/VALUE/VALUE/$FILE"
done < /tmp/filename
Это предполагает, что в файле на каждой строке указан отдельный файл.
Практически во всех случаях, когда вы используете цикл оболочки for
для обработки строк в текстовом файле, лучше использовать awk
или вырезать
или sed
или perl
(или любой другой доступный инструмент для обработки текста). Это будет быстрее, проще и без риска нежелательных побочных эффектов (например, установка IFS перед использованием прочтите
).
Например:
awk '{print "curl -XDELETE '\''ADDRESS:PORT/VALUE/VALUE/"$1"'\''"}' \
/tmp/filename |
sh
(сначала запустите его без подключения к sh, bash, тире и т. Д., Чтобы убедиться, что он выдает правильный результат)
Это делает то, что вы хотите, и помещает URL в одинарные кавычки, чтобы учесть имена файлов. с пробелами, подстановочными знаками глобуса, амперсандами, точками с запятой и т. д. в них. Работает для всех файлов, кроме файлов с одинарными кавычками или новой строкой в имени файла.Последнее невозможно исправить с помощью входного файла, разделенного новой строкой, но первое можно исправить, вставив следующее перед оператором print
:
gsub(/'\''/,"'"'\\\\''"'");
Я недавно написал объяснение того, что это делает здесь: https://unix.stackexchange.com/a/293818/7696
awk '{ gsub(/'\''/,"'"'\\\\''"'");
print "curl -XDELETE '\''ADDRESS:PORT/VALUE/VALUE/"$1"'\''"}' \
/tmp/filename |
sh
Если вы абсолютно уверены, что в именах файлов не будет раздражающих символов, это еще проще:
awk '{ print "curl -XDELETE ADDRESS:PORT/VALUE/VALUE/"$1 }' /tmp/filename | sh