Как использовать sed с переменными пути к файлу И обратными вызовами регулярных выражений И арифметическими выражениями

У меня чертовски сложно получить правильный синтаксис, используя sed с переменными, содержащими путь к файлу, обратный вызов регулярного выражения и арифметическое выражение. Я не знаю, как правильно избегать вещей.

У меня есть путь к файлу в текстовом файле с номером рядом с ним. Я хочу найти эту строку и увеличить число.

FILE="/home/username/scripts/test.txt"
LINE="/home/username/Pictures/properties/wallpaper/span/tree.jpg"

sed -i -e "s,'$LINE' \([0-9]*\),'$LINE' $((\1+1))," $FILE

Например ..

/home/username/Pictures/properties/wallpaper/span/tree.jpg 2

должно стать ..

/home/username/Pictures/properties/wallpaper/span/tree.jpg 3

Каков наилучший способ избежать "." в пути к файлу? Как правильно реализовать обратный вызов \1 и арифметическое выражение $((\1+1)?

В настоящее время я получаю неверный токен \1+1.

2
задан 28 April 2016 в 09:17

1 ответ

sed и арифметика не смешивается. Правильный инструмент для заданий как это awk.

Рассмотрите этот тестовый файл:

$ cat test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
/another/non/matching/line 5

Мы можем увеличить количество строки, с которой Вы хотите:

$ line="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
$ awk -v f="$line" '$0~f {$NF++} 1' test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
/another/non/matching/line 5

Как Вы видите, это увеличило число на строке, которая соответствовала $line.

Одно ограничение - то, что этот код, как записано, не сохранит несколько пробелов на строках, для которых увеличено число. Если бы пробел важен, нам было бы нужно больше определения формата ввода.

Как это работает

  • -v f="$line"

    Это присваивает значение переменной оболочки line к awk переменной f.

  • $0~f {$NF++}

    Здесь, $0~f условие. Это верно если входная строка, обозначенная $0, соответствует regex f как определено выше. Если это соответствует, то оператор $NF++ выполняется. Это увеличивает последнее поле на строке, которая, для Вашего входа, является числом.

  • 1

    Это - загадочное сокращение awk от печати строки.

Редактирование файла, оперативного с awk

Если у Вас есть современный GNU awk, можно отредактировать файл на месте с:

gawk -i inplace -v f="$line" '$0~f {$NF++} 1' test.txt

С другим awks используйте:

awk -v f="$line" '$0~f {$NF++} 1' test.txt > tmp.txt && mv -f tmp.txt test.txt

Создание text.txt если это не существует

В случае, что файл test.txt не содержит соответствие строки $line, эта версия будет такая строка с 1 как количество:

gawk -i inplace -v f="$line" '$0~f {n=1; $NF++} 1; END{if(!n) print f,1>>FILENAME}' test.txt

Этот код добавляет переменную n. Если $line находится в файле, n установлен на 1. Если это не, n остается в значении по умолчанию 0. В END из входного файла, значения n тестируется. Если n все еще нуль, строка добавляется.

3
ответ дан 28 April 2016 в 19:17
  • 1
    Вы имеете в виду json синтаксический анализатор в ударе или в рамках Python? можно ли назвать тот? Существует огромное количество файлов так интересно, мог ли Python быть масштабируемым вообще! – Mona Jalal 27 September 2017 в 13:28

Другие вопросы по тегам:

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