разделить строки файла на основе первого поля

Проблема с параметром Samba mangled namesзаключается в том, что ни один из параметров не является идеальным. У вас могут быть имена, которые не искажены, но к которым нельзя получить доступ каким-либо образом, потому что они содержат недопустимые символы, или имена, которые искажены в формате DOS 8.3 и, следовательно, почти нечитаемы.

К счастью, теперь (есть )модуль VFS с именем catia, который обеспечивает настраиваемые сопоставления символов. В частности, можно отобразить символы, считающиеся недопустимыми в именах файлов Windows.

В разделе [global]поместите эти строки:

    # Mapping illegal characters, where enabled with "vfs objects = catia"
    mangled names = no
    catia:mappings = 0x22:0xa8,0x2a:0xa4,0x2f:0xf8,0x3a:0xf7,0x3c:0xab,0x3e:0xbb,0x3f:0xbf,0x5c:0xff,0x7c:0xa6

В каждом разделе [share_name]добавьте эту следующую строку (, если у вас уже есть строка vfs objects, просто добавьте catiaв список):

    vfs objects = catia

Как обычно, если это будет применяться ко всем вашим общим ресурсам, этот параметр на основе общего ресурса -можно поместить в [global]вместо определения каждого отдельного общего ресурса.

В моей системе на основе Debian -этот объектный модуль VFS был установлен как часть стандартного пакета.

Одним из примеров имени файла, отображаемого этим параметром, является 2017-12-24 12:23.txt. При использовании mangled names = yesэтот файл отображается как 2BB0Y9~4.TXT. Вместо этого при использовании vfs objects = catiaэто имя файла отображается как 2017-12-24 12÷23.txt. Это не идеально, но довольно хорошо. И самое главное, я могу получить к нему доступ из приложений Windows.

0
26.07.2019, 10:29
4 ответа

Вы можете использовать awkи перебирать поля, начиная с 2:

awk -F, '{ OFS=FS; for (i=2;i<=NF;i++) print $1,$i }' file

Выход:

1,a
1,b
1,c
2,b
2,c
3,e
3,f
4,l
4
28.01.2020, 02:14

С sedвы бы сделали

sed -E 's/([^,]*,)([^,]*),/\1\2\n\1/;P;D' file

Обратите внимание, что использование \nв строке замены работает только для GNU sed. В других системах вам нужно будет использовать фактический перевод строки, которому предшествует обратная косая черта:

sed -E 's/([^,]*,)([^,]*),/\1\2\
\1/;P;D' file
  • -Eозначает расширенные регулярные выражения, поэтому я могу использовать ()вместо \(\). Просто для удобства чтения
  • [^,]*соответствует строке без запятой, поэтому соответствует одному полю
  • Таким образом, [^,]*,[^,]*,соответствует первым двум полям. Я поместил ()вокруг полей, чтобы я мог повторно использовать их как \1и \2в замене
  • Команда sзаменяет первые два поля на себя, добавляет новую строку и повторяет первое поле в новой строке. Таким образом, строка разделена на две части :1,a,b,c, одна строка будет с 1,a, а другая — с 1,b,c
  • .
  • Теперь Pпечатает первую строку в буфере (мы знаем, что уже можно печатать)
  • Dудаляет первую строку из буфера и запускает скрипт заново, если после удаления в буфере что-то осталось. Таким образом, оставшиеся 1,b,cснова будут разделены на строки 1,bи 1,c.
  • Если остался только один x,y, шаблон больше не будет совпадать, поэтому новая строка не вставляется, а sedне циклически повторяется, а продолжается со следующей строки
2
28.01.2020, 02:14

Использование Миллера(https://github.com/johnkerl/miller)

mlr --c2n --ofs "," --implicit-csv-header then reshape -r "[^1]" -o item,value then cut -x -f item input.txt

вы получите на выходе

1,a
1,b
1,c
2,b
2,c
3,e
3,f
4,l
2
28.01.2020, 02:14

Вы можете выполнить эту задачу различными способами, как показано ниже:

$ sed -e ':a
    s/,/\n/2;/\n/!b
    P;s/,.*\n/,/;ba
' file.csv

Пояснение:

Мы пытаемся заменить вторую запятую новой строкой. Если это невозможно => пространство шаблонов было меньше двух и, следовательно, должно быть передано в стандартный вывод.

OTW, мы печатаем первые две запятые -поля, разделенные -, затем удаляем второе поле, чтобы третье теперь стало вторым и так далее.

$ perl -F,  -lane '
    my $f1 = shift @F;
    print join ",", $f1, $_ for @F;
' file.csv

Пояснение:

Разделите каждую строку на поля через запятую, и perlсохранит поля в массиве @F. Первое поле мы смещаем из массива @F и сохраняем в скаляре $f1. Затем последовательно печатайте элементы массива.

$ perl -F\(,\) -lane '
    my $f1 = shift @F;
    print $f1, splice @F, 0, 2 while @F > 1 ;
' file.csv

$ perl -F, -lane 'print $F[0], $_ for /,(?:(?!,).)*/g' file.csv

$ sed -Ee 's/,?[^,]*/[&] /g'  file.csv |
   dc -e "
   [q]sq
   [SMlN1+sNz1<a]sa
   [dnLMn10anlN1-dsN0<b]sb
   [?z0=q0sNlaxlbxclcx]sclcx
"

Результат:

 1,a
 1,b
 1,c
 2,b
 2,c
 3,e
 3,f
 4,l
0
28.01.2020, 02:14

Теги

Похожие вопросы