Проблема с параметром 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.
Вы можете использовать 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
С 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
не циклически повторяется, а продолжается со следующей строки Использование Миллера(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
Вы можете выполнить эту задачу различными способами, как показано ниже:
$ 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