Чтение строк из файла в переменную

Прошу прощения, но ваш пример 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 имеет две ошибки:

  1. Вы используете расширенный синтаксис регулярного выражения. Вы можете использовать его, только если у вас есть gnu sed. Разница в том, как они используют круглые скобки.
  2. Вы должны считать обратные ссылки, начиная с 1 .

Итак, правильная команда:

echo  "\"john.doe@gmail.com\"" | sed 's/"\([^"]*\)"/\1/g' 

или, если ваш sed поддерживает расширенное регулярное выражение:

echo "\"john.doe@gmail.com\"" | sed -E 's/"([^"]*)"/\1/g'
1
07.07.2016, 02:40
3 ответа

Это для строки:

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 ).

1
27.01.2020, 23:19

В этом for вы просто делаете одну итерацию, где значение $FILE является значением $LISTFILE.

Если вы хотите перебирать строки в файле, вы можете использовать read:

while read -r FILE; do
    curl -XDELETE "ADDRESS:PORT/VALUE/VALUE/$FILE"
done < /tmp/filename

Это предполагает, что в файле на каждой строке указан отдельный файл.

3
27.01.2020, 23:19

Практически во всех случаях, когда вы используете цикл оболочки 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
0
27.01.2020, 23:19

Теги

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