انجمنهای فارسی اوبونتو
کمک و پشتیبانی => انجمن عمومی => نویسنده: zahra.shl در 23 تیر 1399، 10:11 قظ
-
سلام دوستان
من یک سوال کامند نویسی در منحیط لینوکس داشتم. دوستان من یک فایل به صورت تکست دارم و می خواهم اولین عدد هر پاراگراف را مقایسه کند و اگر برابر باشند آن ها را در یک پاراگراف چاپ کند . در غیر این صورت آن ها را در پاراگراف متفاوت چاپ کند. چطوری میتونم در لینوکس این کار را انجام بدهم؟
متشکرم
-
سلام دوستان
من یک سوال کامند نویسی در منحیط لینوکس داشتم. دوستان من یک فایل به صورت تکست دارم و می خواهم اولین عدد هر پاراگراف را مقایسه کند و اگر برابر باشند آن ها را در یک پاراگراف چاپ کند . در غیر این صورت آن ها را در پاراگراف متفاوت چاپ کند. چطوری میتونم در لینوکس این کار را انجام بدهم؟
متشکرم
فکر نکنم چنین قابلیتی رو کد های شل داشته باشن باید از زبان های برنامه نویسی استفاده کنید
-
سوالتون شبیه یک تمرین هست. برای اینکه بتونیم راهنماییتون کنیم بهتر هست یک ورودی و خروجی نمونه قرار بدید.
به نظر میاد باید با ابزاری مثل awk این کار رو انجام بدید.
-
ممنون از پاسخ گوپپتان ورودی من فایلی مثل فایل زیر هست
ورودی من
a 1
1 b
1 d
2 c
2 e
خروجی که میخام
1 a b d
2 c e
-
احتمالا با awk می شود ولی اینجا من با دستور R این مسئله رو حل کردم.
A = data.frame(C1=c("a","b","d","c","e"),C2=c(1,1,1,2,2))
write.table(tapply(A$C1,A$C2,function(x)paste(x,collapse=" ")),quote=F,col.names=F)
فقط اعداد اول چاپ می شوند بعد حروف. این مشکل را می شود حل کرد ولی احتمالا نه در یک خط.
-
تشکر از پاسخ گوییتان
باید با کامندای لینوکس این کار رو انجام بدم چند روزه درگیرش شدم اما متاسفانه هنوز به جوابی نرسیدم.
-
تشکر از پاسخ گوییتان
باید با کامندای لینوکس این کار رو انجام بدم چند روزه درگیرش شدم اما متاسفانه هنوز به جوابی نرسیدم.
تمرین دانشگاه است:)؟
-
بله.
-
اینجا فقط می تونیم راهنماییتان کنیم نه اینکه تمرین را حل کنیم.
ولی خوب اگر نمی خواهید آر را اجرا کنید این کلک مرغابی را می تونید بزنید:
r -tpe 'A = data.frame(C1=c("a","b","d","c","e"),C2=c(1,1,1,2,2));write.table(tapply(A$C1,A$C2,function(x)paste(x,collapse=" ")),quote=F,col.names=F)'
من به دلیل بالا (آر کارم راه می اندازد و اگر نداخت سی دو مثبت استفاده می کنم) از awk به ندرت استفاده می کنم. AWK یک زبان برنامهنویسی مفسری:
https://fa.wikipedia.org/wiki/AWK
(https://fa.wikipedia.org/wiki/AWK)
که به احتمال زیاد می تواند این مشکل را حل کند.
https://www.grymoire.com/Unix/Awk.html
(https://www.grymoire.com/Unix/Awk.html)
-
من بعید میدونم طراح سوال قصد داشته باشه شما با awk مسئله رو حل کنید. به همین خاطر من پاسخ رو با awk براتون مینویسم ولی بهتر هست با حلقه و آرایه خودتون مسئله رو حل کنید. ایکاش توضیح میدادید تا الان چه کار کردید و به چه نتایجی رسیدید!
فرض کنید دادهها درهم ریخته باشند:
$ cat file
a 1
b 2
c 3
d 2
e 2
f 1
g 3
میتونیم با ترکیب sort و awk مسئله رو حل کنیم. مرتب کردن دادههای ما رو به این شکل در میاره:
$ sort --numeric-sort -k 2 file
a 1
f 1
b 2
d 2
e 2
c 3
g 3
$ sort --numeric-sort -k 2 file | awk 'NR>1 && $2!=ll { printf ll; print "" }{ ll=$2 } {printf $1" "} END {printf ll}'
خروجی:
a f 1
b d e 2
c g 3
قسمت awk رو از لینک دومی که alend قرار داد خودتون کمی مطالعه کنید تا متوجه بشید چه اتفاقی داره رخ میده!
-
#!/bin/bash
numberOfLines=`wc -l $1 | tr -dc '0-9'`
# this loop create two arrays for numbers and characters
for (( i=0; i<$numberOfLines; i=i+1 )); do
declare -a numberList
numberList+=(`head -n $(( i+1 )) $1 | tail -1 | tr -dc '0-9'`)
declare -a characterList
characterList+=(`head -n $(( i+1 )) $1 | tail -1 | tr -dc 'a-z'`)
done
uniqueNumberList=($(echo "${numberList[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) # this create an array from unique numbers in lines
create_line(){
# this loop create a list from index of a unique number in numberList
for i in "${!numberList[@]}"; do
if [[ "${numberList[$i]}" -eq $1 ]]; then
declare -a myList
myList+=(${i});
fi
done
# this loop create a line contain characters
generatedLine=""
for j in "${myList[@]}"; do
generatedLine+="${characterList[$j]} "
done
}
# this loop create output value
for k in "${uniqueNumberList[@]}"; do
create_line $k
echo "$generatedLine$k"
done
کد بالا را در یک فایل به نام exam.sh ذخیره کنید و مجوز اجرا به اون بدید
chmod 755 exam.sh
برای اجرا هم از کامند زیر استفاده کنید:
./exam.sh filename
به جای filename اسم فایل مدنظر رو قرار بدید
...
ببخشید شاید یه مقدار موضوعو پیچیده کردم ولی اینم یه راه حل جالب بود که به ذهنم رسید :)
-
#!/bin/bash
numberOfLines=`wc -l $1 | tr -dc '0-9'`
# this loop create two arrays for numbers and characters
for (( i=0; i<$numberOfLines; i=i+1 )); do
declare -a numberList
numberList+=(`head -n $(( i+1 )) $1 | tail -1 | tr -dc '0-9'`)
declare -a characterList
characterList+=(`head -n $(( i+1 )) $1 | tail -1 | tr -dc 'a-z'`)
done
uniqueNumberList=($(echo "${numberList[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) # this create an array from unique numbers in lines
create_line(){
# this loop create a list from index of a unique number in numberList
for i in "${!numberList[@]}"; do
if [[ "${numberList[$i]}" -eq $1 ]]; then
declare -a myList
myList+=(${i});
fi
done
# this loop create a line contain characters
generatedLine=""
for j in "${myList[@]}"; do
generatedLine+="${characterList[$j]} "
done
}
# this loop create output value
for k in "${uniqueNumberList[@]}"; do
create_line $k
echo "$generatedLine$k"
done
کد بالا را در یک فایل به نام exam.sh ذخیره کنید و مجوز اجرا به اون بدید
chmod 755 exam.sh
برای اجرا هم از کامند زیر استفاده کنید:
./exam.sh filename
به جای filename اسم فایل مدنظر رو قرار بدید
...
ببخشید شاید یه مقدار موضوعو پیچیده کردم ولی اینم یه راه حل جالب بود که به ذهنم رسید :)
من نمی دونم چرا وقتی اسکریپت های بش مثل این را می بینم فکر می کنم سی دو مثبت از بش ساده تر است ;D.