Если у вас есть GNU sed, вы можете сделать это:
sed -i 's/\x0D$//' script
Где «x0D» - это код ASCII для \ r.
Ответ на пересмотренный вопрос:
sed -r 's/(~[^~]*~)?,/\1;/g' infile
~new file: 12345~;~125.5~;;;~ example (45), case (20)~;;
~file (54) ~;;~5.5~;;~ this is a sample.~;;~end; end~
~line 3~;~3.6~;~0.0~;~hello~;~hello, world~;~6.7~;~end of line~
заменить все ~...~,
на ~...~;
, где ~...~
может быть необязательным.
Чтобы подсчитать количество столбцов в каждой строке, с awk
вы можете сделать:
awk -F, '{ gsub(/~[^~]*~/,""); print NF }' infile
для ввода типа:
~new file: 12345~,~125.5~,,,~ example (45), case (20)~,,
,~125.5~,,,~ example (45), case (20)~
Он вернется:
7
5
В gsub(/~[^~]*~/,"")
мы заменяем каждый шаблон, начинающийся с ~
до следующего ~
, видимого (, например ~...~
), пустой строкой; см. ниже:
awk -F, '{ gsub(/~[^~]*~/,""); print $0 }' infile
,,,,,,
,,,,
Это предполагает, что во входных данных нет внутреннего ~
, такого как ,~some~thing~,
.
, затем print NF
напечатает количество полей в соответствии с указанным разделителем полей -F
.
,
- разделитель столбцов... Я бы просто запустил команду column
следующим образом:
column -s',' -t -o',' original_data.txt > output.csv
Пояснение:
-t, --table create a table
-s, --separator <string> possible table delimiters
-o, --output-separator <string>
выход:
cat output.csv
~new file: 12345~,~125.5~, , ,~ example (45) , case (20)~, ,
~file (54) ~ , ,~5.5~, ,~ this is a sample.~, ,~end, end~
~line 3~ ,~3.6~ ,~0.0~,~hello~,~hello , world~ ,~6.7~,~end of line~
Обратите внимание , как запятая в файле output.csv создавала границы между столбцами.
Если вы хотите избавиться от ~
, вы можете использовать sed
или tr
после column
что-то вроде:
column -s',' -t -o',' original_data.txt | tr -d "~" > output.csv
выход
cat output.csv
new file: 12345,125.5, , , example (45) , case (20), ,
file (54) , ,5.5, , this is a sample., ,end, end
line 3 ,3.6 ,0.0,hello,hello , world ,6.7,end of line
Это похоже на CSV-файл, в котором используются запятые в качестве разделителей полей и тильда в качестве символа кавычек.
Использование надлежащего синтаксического анализатора CSV, подобного тому, который предоставляется модулем Text::CSV
Perl:
perl -MText::CSV -e 'print scalar(@{Text::CSV->new({quote_char=>"~"})->getline(\*STDIN)})' <file.csv
При этом будет прочитана первая строка CSV-файла file.csv
и напечатано количество столбцов в ней. Мы создаем синтаксический анализатор, который понимает, что символ кавычки — это тильда, прежде чем читать первую строку с помощью этого синтаксического анализатора. Метод getline()
этого синтаксического анализатора будет читать строку из заданного дескриптора файла и возвращать ссылку на массив данных, по одному элементу на проанализированный столбец. print scalar(...)
— довольно распространенный способ печати длины массива в Perl.
Другой способ, используя CSVKit набор инструментов парсера CSV командной строки:
csvstat -n -q '~' <file.csv | wc -l
или эквивалентно, используя длинные опции,
csvstat --names --quotechar '~' <file.csv | wc -l
Аналогичным образом будет прочитана первая строка входного файла и возвращен список заголовков. (Первая строка CSV-файла обычно содержит заголовки столбцов ), по одному на строку. wc -l
подсчитывает количество возвращенных строк.
Команда csvstat
сама по себе (безwc -l
)возвращает
1: new file: 12345
2: 125.5
3:
4:
5: example (45), case (20)
6:
7:
Когда вы позже будете анализировать CSV-файл, я предлагаю вам использовать один из этих подходов или поискать подходящий анализатор на языке программирования, к которому вы больше всего привыкли. awk
и sed
можно использовать для простых данных CSV,но в этом случае ваши данные используют некоторые функции формата CSV, с которыми этим инструментам было бы трудно справиться без особой осторожности.