Или более сложно, но с одним проходом файловой системы (для еще большей переносимости ~
следует записать как $ HOME
])
find . \( -type d -exec mkdir -p "~/elsewhere/{}" \; \
-o -type f -exec touch "~/elsewhere/{}" \; \)
Сложность здесь заключается в логике (которую может быть полезно изучить) и приоритета (также полезно знать), а также в том, как find
реализует эти концепции с неявным И между -тип
и последующее действие, а также ИЛИ, появляющееся как -о
.
Я уверен, что есть более эффективные способы решения этой проблемы, но эта пара awk
скриптов выполнит свою работу. Вы можете использовать либо увеличенную версию с комментариями, либо однострочную версию ниже; они функционально идентичны.
awk '
BEGIN { RS="" } # Slurp paragraphs
{ print gensub("\n", " ", "g") } # Replace NL with SPACE
' /tmp/tnsnames.ora | # ...in this file
awk '
/SERVICE_NAME/ { # Only process matching lines
listener=$1; # Listener is the first field
si=NF-2; # Count fields back from end of string
service=gensub(")", "", 1, $si); # Strip trailing ")"
printf "%s\t%s\n", listener, service # Output result
}
'
Пример выполнения
awk 'BEGIN { RS="" } { print gensub("\n", " ", "g") }' /tmp/tnsnames.ora | awk '/SERVICE_NAME/ { listener=$1; si=NF-2; service=gensub(")", "", 1, $si); printf "%s\t%s\n", listener, service }'
NEWDB newdb
STEST STEST
RBSDB RBSDB
perl -l -00ne '
my ($blk) = /^\w+/g;
$np = qr/
\( # match an opening paren
(?:
(?> [^)(]+ ) # one or more non paren, non backtracking
|
(??{ $np }) # recurse for more
)*
\) # match a closing paren
/x;
1 while
/$np
(?{
m{ \( CONNECT_DATA \s+ = (?:\s*$np\s*)+ \) }x and
m{ \( SERVICE_NAME \s+ = \s+ (\w+) \) }x and
print join $", $blk, $1 for $&;
})
/gx;
' input_file
NEWDB newdb
STEST STEST
RBSDB RBSDB