Sed & Ma c OS Terminal: Как убрать содержимое скобок из первой строки каждого файла? - PullRequest
0 голосов
/ 14 января 2020

Я на Ма c Os 10.14.6 и у меня есть каталог, который содержит подкаталоги, которые все содержат текстовые файлы. В целом, существует много сотен текстовых файлов.

Я бы хотел go просмотреть текстовые файлы и проверить наличие содержимого в первой строке в скобках. Если такой контент найден, то скобки (и контент в скобках) должны быть удалены.

Пример:

До удаления:

The new world (82 edition)

После удаления:

The new world 

Как мне это сделать?


Шаги, которые я пробовал:

Google вокруг, кажется, SED будет лучше для этого. Я нашел эту ветку , которая предоставляет код SED для удаления содержимого в скобках.

sed -e 's/([^()]*)//g'

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

Обратите внимание: пока решение работает на терминале ОС Ma c, тогда ему не нужно использовать SED. Тем не менее, от Google, SED, кажется, наиболее подходит.

Ответы [ 3 ]

1 голос
/ 14 января 2020

Мне удалось добиться того, что вам нужно, просто используя сценарий bash и sed вместе, вот так:

#!/bin/bash

for filename in $PWD/*.txt; do
    sed -i '' '1 s/([^()]*)//g' $filename
done

Этот сценарий просто перебирает все файлы .txt в $ PWD (текущий рабочий каталог, так что вы можете добавить этот скрипт в свой бен и запускать его где угодно), а затем выполнить команду

sed -ie '1 s/([^()]*)//g' $filename

для файла. Запустив команду с номером 1, мы сообщаем, что sed должен работать только с первой строкой файла:)

Редактировать: Лучший ответ

Работает выше штраф в каталоге, где все содержащиеся объекты являются файлами, не включая каталоги; другими словами, вышеприведенное не выполняет рекурсивный поиск по каталогам.

Поэтому после некоторого исследования эта команда должна выполнить именно то, что задает вопрос:

find . -name "*.txt" -exec sed -i '' '1 s/([^()]*)//g' {} \;

I must повторяем и повторяем, что вы сначала проверяете это на резервной копии, чтобы проверить, работает ли она. В противном случае используйте ту же команду, что и выше, но измените '', чтобы контролировать создание резервных копий. Например,

find . -name "*.txt" -exec sed -i '.bkp' '1 s/([^()]*)//g' {} \;

Эта команда выполнит замену sed в исходном файле (сохраняя имя файла), но создаст файл резервной копии для каждого с добавленным .bkp, например, test1.txt становится test1.txt.bkp. Это более безопасный вариант, но выберите наиболее подходящий для вас:)

1 голос
/ 14 января 2020

Хорошая попытка,

Команда, которую вы ищете в одной строке:

sed -E '1s|\([^\)]+\)||'

Команда для замены каждого входного файла первой строкой:

sed -Ei '1s|\([^\)]+\)||' *.txt

пример :

echo "The new world (82 edition)" |sed -E '1s|\([^\)]+\)||'
The new world

Пояснение

sed -Ei E опция: расширенный синтаксис RegExp, i опция: для замены файла на месте

sed -Ei '1s|match RegExp||' только для первой строки: замените первую совпадающую строку RegExp пустой строкой

\([^\)]+\) Соответствие RegExp: начинайте с (, [^\)] любой символ не ), + - более одного раза, завершается с )

0 голосов
/ 15 января 2020

Попробуйте:

# create a temporary file
tmp=$(mktemp)

# for each something in _the current directory_
for i in *; do
    # if it is not a file, don't parse it
    if [ ! -f "$i" ]; then continue; fi
    # remove parenthesis on first line, save the output in temporary file
    sed '1s/([^)]*)//g' "$i" > "$tmp"
    # move temporary file to the original file
    mv "$tmp" "$i"
done

# remove temporary file
rm "$tmp"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...