Не уверен, насколько сложным может быть ваш файл, но для приведенного примера это работает.
$ awk '/^<[a-z]/{print;delete z}!/^</{z[$0]=1}/^<\//{for(x in z){print x}print}' file1
<tag2>
a
b
c
</tag2>
<tag2>
x
y
z
</tag2>
$
Версия с комментариями
awk '/^<[a-z]/ { # If start tag
print # Print line
delete z # Clear array
} !/^</ { # If not a tag
z[$0]=1 # Store line
} /^<\// { # If end tag
for(x in z) { # For each array entry
print x # Print array entry
}
print # Print end tag
}' file1
-i
являетсяsed
-специфичным. Например, awk
будет -i inplace
, а многие другие даже не поддерживают действия в -месте.
Существует ряд соглашений. Наиболее важным является то, что если ввод не указан, используйте STDIN, а если вывод не задан, используйте STDOUT. Но тот, который вы уже делаете.
Как правило, большинство программ обрабатывают список файлов в командной строке как файлы, которые необходимо прочитать. Многие программы используют -o filename
, чтобы указать, что вывод должен идти на filename
. Похоже, GNU нравится --output
и за это.
Если вы хотите явно использовать STDIN или STDOUT, --
кажется более или менее стандартным способом указать это.
Но есть много программ, которые не следуют этому соглашению. Некоторые используют последний позиционный аргумент для вывода. Некоторые используют --
, чтобы указать, что остальная часть командной строки содержит только файлы, а некоторые (, такие как dd
), создали свой собственный стандарт.
Итак, на вашем месте я бы придерживался-o
и--output
для выходного файла и использовал --
для STDIN или STDOUT. И напишите четкую справочную страницу, чтобы ваша программа стала предсказуемой.