
Я анализирую текстовый файл, ищу путь, который написан после строки, начинающейся с "output". Строка выглядит примерно так
output xyz/mypath/
и я хочу извлечьxyz/mypath
безпоследний штрих.
На моем Mac OS X (BSD) и Linux я получаю разное поведение, когда получаю путь с помощью этого
basepath=cat $basefile | grep -e ^output\ | cut -d" " -f2 | rev | sed 's@/$@@' | rev
Кажется, самая сложная часть заключается в том,
sed 's@/$@@
который на Mac работает, а на Linux нет. И наоборот, если я делаю
sed 's@/@@
он работает на Linux, но не на Mac (BSD).
Похоже, трюк связан с символом конца строки $, который обрабатывается по-разному (возможно, на уровне cat). Есть ли у вас предложения, как обойти это так, чтобы и консоль Mac, и консоль Linux справились с этой задачей?
решение1
У меня нет легкого доступа к машине OSX, но ваш подход в любом случае излишне сложен. Просто сделайте что-то вроде этого (в зависимости от вашего фактического ввода) вместо этого:
basepath=$(grep ^output "$basefile" | awk '{print $NF}' | sed 's/[/]$//'
или
basepath=$(awk '/^output/{print $2}' "$basefile" | sed 's/[/]$//')
или даже
basepath=$(grep -oP '^output\s+\K.+(?=/)' "$basefile")
или
basepath=$(perl -lne 'print $1 if /^output\s+(.+)\//' "$basefile";
решение2
Насколько я могу судить, это должно работать в Linux в том виде, в котором есть, sed
по крайней мере, это выражение, но если вы хотите узнать, что происходит в sed
пространстве шаблонов , то вам следует l
взглянуть на него:
sed 'l;s|/$||;l'
Я думаю, вы могли бы сделать все это sed
примерно так:
basepath=$(sed '/^output /!d;s|||;s|/$||' <"$basefile")
решение3
Я бы предложил
sed -n '/^output / {s///; s,\(.*\)/,\1,p}'
который должен работать на GNU и OSX sed.
Пустое регулярное выражение s///
повторно использует предыдущее регулярное выражение ( /^output /
)