Предположим, что это обычные файлы без пробелов, символов новой строки, кавычек, обратной косой черты или недопустимых символов в их путях:
find /target/dir/ -type f \
| awk '{t=$0; gsub(/\/[^/]*$/, "", t); if(a[t]++ < 4) print}' \
| xargs rm --
См. комментарии ниже, чтобы узнать, как вы могли бы адаптировать его для более забавных имен файлов, если ваши утилиты поддерживают определенные расширения.
Вы можете использовать sed
, чтобы вырезать ненужные символы:
sed 's/[^0-9.T:-]\+/,/g;s/T/ /;s/^,\|,$//g' file
s / [^ 0-9. T: -] \ + /, / g
заменяет ненужные символы запятой
s / T / /
заменяет символ T
пробелом
s / ^, \ |, $ // g
удаляет первую и последнюю запятую
Предположим, что f.xml
- это наш ввод (действительный xml):
$ perl -MXML::DT -E 'dt("f.xml",
time=>sub{$a=father;
$c =~ s/[TZ]/ /g;
say "$a->{lat},$a->{lon},$c"}
)'
-MXML :: DT
загрузить модуль XML :: DT (переводчик вниз xml) dt (файл , time => sub {....})
: анализируйте файл и каждый раз, когда мы видим раз
, выполняем соответствующий sub $ a = Father
: получаем атрибуты из отец $ c
: это текущее содержимое элемента Предупреждение: я являюсь одним из авторов XML :: DT (устанавливается с cpan XML :: DT
)
этот ответ основан на введенных данных ...
awk -F"[<>\"]" '{print $3,$5,$9}' OFS=, input.txt | sed "s/[TZ]/ /g"
1.345529841,103.7577152,2010-01-01 00:00:00
1.345529841,103.7577152,2010-01-01 00:00:00
1.3982529841,103.90877152,2010-01-01 00:00:00
awk -F"[<>\"]" '{gsub(/T|Z/," ",$9);print $3,$5,$9}' OFS=, input.txt
Пожалуйста, не используйте регулярные выражения на основе решение, например awk
или sed
.
XML
является контекстным, в то время как регулярные выражения не являются - , поэтому они НИКОГДА не могут работать должным образом, это в лучшем случае лишь небольшая хитрость .
Но у XML есть решение этой проблемы - он называется xpath
, что позволяет «искать» контекстным способом.
Итак, возьмем ваш пример:
#!/usr/bin/perl
use warnings;
use strict;
use XML::Twig;
my $xml = XML::Twig -> new -> parsefile('your_file.xml');
foreach my $wpt ( $xml -> get_xpath('//wpt') ) {
print join ",", $wpt -> att('lat'),
$wpt -> att('lon'),
$wpt -> first_child_text('time'), "\n";
}
Что дает желаемый результат, но также будет обрабатывать множество совершенно корректных и семантически идентичных форм вашего XML.
Как с отступом:
<xml>
<wpt lat="1.345529841" lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt lat="1.345529841" lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt lat="1.3982529841" lon="103.90877152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
</xml>
Все в одной строке:
<xml><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.345529841" lon="103.7577152"><time>2010-01-01T00:00:00Z</time></wpt><wpt lat="1.3982529841" lon="103.90877152"><time>2010-01-01T00:00:00Z</time></wpt></xml>
Другой стиль отступа:
<xml>
<wpt
lat="1.345529841"
lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt
lat="1.345529841"
lon="103.7577152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt
lat="1.3982529841"
lon="103.90877152">
<time>2010-01-01T00:00:00Z</time>
</wpt>
</xml>
Или даже:
<xml
><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.345529841"
lon="103.7577152"
><time
>2010-01-01T00:00:00Z</time></wpt><wpt
lat="1.3982529841"
lon="103.90877152"
><time
>2010-01-01T00:00:00Z</time></wpt></xml>
Все они семантически идентичны, и следует анализировать одинаково способ. Надеюсь, совершенно ясно, что регулярное выражение для этого НАМНОГО сложнее, чем использование парсера XML.
Для краткости:
perl -MXML::Twig -0777 -e 'XML::Twig->new(twig_handlers=>{wpt=>sub{print join ",", $_->att("lat", $_->att("lon"),$_->first_child_text("time"), "\n" }})->parse(<>)'
GPX - это формат XML , поэтому вы не можете использовать awk
или sed
для его надежного анализа.
Вместо этого используйте что-то вроде XMLStarlet :
$ xml sel -t -m '//wpt' \
-v '@lat' -o ',' -v '@lon' -o ',' \
-v 'time' -nl data.gpx
1.345529841,103.7577152,2010-01-01T00:00:00Z
1.345529841,103.7577152,2010-01-01T00:00:00Z
1.3982529841,103.90877152,2010-01-01T00:00:00Z
В качестве альтернативы:
$ xml sel -t -m '//wpt' -v 'concat(@lat, ",", @lon, ",", time)' -nl data.wpx
sed "s/[^0-9.:-]/ /g" j.txtK| sed -r "s/\s+/ /g"| sed -r "s/^\s+//g"|awk 'OFS=","{print $1,$2,$3" " $4}'
выход
1.345529841,103.7577152,2010-01-01 00:00:00
1.345529841,103.7577152,2010-01-01 00:00:00
1.3982529841,103.90877152,2010-01-01 00:00:00